home *** CD-ROM | disk | FTP | other *** search
/ Alles Voor Internet / Tout Pour Internet / alles voor internet.iso / MacInternet™ / Telnet / NCSA / tn3270 2.3d26 source / tn3270 / writetm.c < prev   
Text File  |  1991-04-08  |  14KB  |  669 lines

  1. /*
  2.  *  tn3270 for the Macintosh Source Code
  3.  *  Brown University Computing and Information Services
  4.  *  Version 2.3d21, January 17, 1991
  5.  *  Copyright (c) 1988, 1989, 1990, 1991 by Brown University and by
  6.  *  Peter John DiCamillo.
  7.  *
  8.  *  Permission is granted to any individual or institution to use, copy,
  9.  *  or redistribute the binary version of this software and its
  10.  *  documentation provided this notice and the copyright notices are
  11.  *  retained.  Permission is granted to any individual or non-profit
  12.  *  institution to use, copy, modify, or redistribute the source files
  13.  *  of this software provided this notice and the copyright notices are
  14.  *  retained.  This software may not be distributed for profit, either
  15.  *  in original form or in derivative works, nor can the source be
  16.  *  distributed to other than an individual or a non-profit institution.
  17.  *  Any  individual or group interested in seeing and/or using these
  18.  *  source files but who are prevented from doing so by the above
  19.  *  constraints should contact Don Wolfe, Assistant Vice-President for
  20.  *  Computer Systems at Brown University, (401) 863-7250, for possible
  21.  *  software licensing of the source developed at Brown.
  22.  *
  23.  *  Brown University and Peter John DiCamillo make no representations
  24.  *  about the suitability of this software for any purpose.
  25.  *
  26.  *  BROWN UNIVERSITY AND PETER JOHN DICAMILLO GIVE NO WARRANTY, EITHER
  27.  *  EXPRESS OR IMPLIED, FOR THE PROGRAM AND/OR DOCUMENTATION PROVIDED,
  28.  *  INCLUDING, WITHOUT LIMITATION, WARRANTY OF MERCHANTABILITY AND
  29.  *  WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE.
  30.  *
  31.  */
  32.  
  33. #define __SEG__ 3270seg1
  34.  
  35. #include "maclib.h"
  36. #include "termdef.h"
  37. #include "globals.h"
  38.  
  39. extern unsigned char ordertab[];
  40. extern short maxoff, maxcnt, scrhsize;
  41. char colorfield = 0;
  42. extern Rect selrect;        /* rectangle for last text selection */
  43. static short attrloc = 0;    /* location where last attribute was stored */
  44. char skipnewmode;            /* skip call to newmode for EW/EWA */
  45.  
  46. writetm(cmd, len, init)
  47. unsigned char * cmd;
  48. short len;
  49. char init;
  50. {
  51. register short left;
  52. register short size;
  53. register unsigned char c, ew;
  54.  
  55. if (init) {
  56.     ew = 0;                        /* erase/write flag */                     
  57.     if ((cmd[0] & 0x07) >= 5) {        /* interpret op-code */
  58.         ew = 1;
  59.         if (skipnewmode == 0) {
  60.             if (((cmd[0] & 0x0f) == 0x0d) || (cmd[0] == 0x7e)) {    /* ewa */
  61.                 ewamode = 1;
  62.                 }
  63.             else {                        /* possible end of ewa */
  64.                 ewamode = 0;
  65.                 }
  66.             newmode(ewamode, 0);
  67.             }
  68.         clrscn();
  69.         }
  70.     intwcc(ew, cmd[1]);            /* interpret WCC */
  71.     ldvoff = 2;                    /* skip to start of data */
  72.     ptfill = 0;
  73.     chratr = 0;
  74.     bufadr = curadr;            /* buffer address starts out at cursor */
  75.     }
  76.  
  77. while (ldvoff < len) {
  78.                                 /* special code to handle data quickly */
  79.     c = cmd[ldvoff++];
  80.     if (ordertab[c]) {
  81.         chrbuff[bufadr] = c;
  82.         atrbuff[bufadr] = chratr;
  83.         if ((c == 0xad) || (c == 0xbd))
  84.             if (fixbracket) atrbuff[bufadr] += 0x4000;
  85.         bufadr++;
  86.         if (bufadr == maxcnt) bufadr = 0;
  87.         ptfill = 1;
  88.         continue;
  89.         }
  90.     else ldvoff--;
  91.                                 /* order processing code */
  92.     left = len - ldvoff;
  93.     switch(cmd[ldvoff]) {
  94.         case 0x1D:        /* Start Field */
  95.                 if (left < 2) return;
  96.                 intsf(cmd[ldvoff+1]);
  97.                 ldvoff += 2;
  98.                 ptfill = 0;
  99.                 break;
  100.  
  101.         case 0x11:        /* Set Buffer Address */
  102.                 if (left < 3) return;
  103.                 intsba(cmd[ldvoff+1], cmd[ldvoff+2]);
  104.                 ldvoff += 3;
  105.                 ptfill = 0;
  106.                 break;
  107.  
  108.         case 0x13:        /* Insert Cursor */
  109.                 intic();
  110.                 ldvoff++;
  111.                 ptfill = 0;
  112.                 break;
  113.  
  114.         case 0x05:        /* Program Tab */
  115.                 intpt();
  116.                 ldvoff++;
  117.                 break;
  118.  
  119.         case 0x3C:        /* Repeat to Address */
  120.                 if (left < 4) return;
  121.                 c = cmd[ldvoff+3];
  122.                 if (c == 0x08) {
  123.                    if (left < 5) return;
  124.                    c = cmd[ldvoff+4];
  125.                    intra(cmd[ldvoff+1], cmd[ldvoff+2], c, 1);
  126.                    ldvoff += 5;
  127.                    }
  128.                 else {
  129.                    intra(cmd[ldvoff+1], cmd[ldvoff+2], c, 0);
  130.                    ldvoff += 4;
  131.                    }
  132.                 ptfill = 0;
  133.                 break;
  134.  
  135.         case 0x12:        /* Erase Unprotected to Address */
  136.                 if (left < 3) return;
  137.                 inteua(cmd[ldvoff+1], cmd[ldvoff+2]);
  138.                 ldvoff += 3;
  139.                 ptfill = 0;
  140.                 break;
  141.  
  142.         case 0x08:        /* Graphics Escape */
  143.                 if (left < 2) return;
  144.                 intdata(cmd[ldvoff+1], 1);
  145.                 ldvoff += 2;
  146.                 break;
  147.  
  148.         case 0x29:        /* Start Field Extended */
  149.                 if (left < 2) return;
  150.                 size = (cmd[ldvoff+1]+1) * 2;
  151.                 if (left < size) return;
  152.                 intsfe(cmd+ldvoff+2, cmd[ldvoff+1]);
  153.                 ldvoff += size;
  154.                 ptfill = 0;
  155.                 break;
  156.  
  157.         case 0x2C:        /* Modify Field */
  158.                 if (left < 2) return;
  159.                 size = (cmd[ldvoff+1]+1) * 2;
  160.                 if (left < size) return;
  161.                 intmf(cmd+ldvoff+2, cmd[ldvoff+1]);
  162.                 ldvoff += size;
  163.                 ptfill = 0;
  164.                 break;
  165.  
  166.         case 0x28:        /* Set Attribute */
  167.                 if (left < 3)  return;
  168.                 intsa(cmd[ldvoff+1], cmd[ldvoff+2]);
  169.                 ldvoff += 3;
  170.                 ptfill = 0;
  171.                 break;
  172.  
  173.         default:        /* shouldn't happen */
  174.                 break;
  175.         }
  176.     }
  177. }
  178.  
  179. clrscn()
  180. {
  181. setmem(chrbuff, maxcnt, 0);
  182. setmem(atrbuff, maxcnt<<1, 0);
  183. curadr = 0;
  184. bufadr = 0;
  185. colorfield = 0;
  186. textsel = 0;
  187. fmtscrn = 0;
  188. }
  189.  
  190. intwcc(ew, wcc)
  191. unsigned char ew, wcc;
  192. {
  193. register short i;
  194. register char code;
  195.  
  196. lastwcc = wcc & 0x7f;
  197. if (wcc & 0x01) for (i=0; i < maxcnt; i++) {
  198.     atrbuff[i] &= 0xFEFF;
  199.     }
  200. kb_err = 0;
  201. if (kblock) {
  202.     lastwcc |= 0x80;    /* remember was locked */
  203.                         /* indicate SYSTEM immediately */
  204.     if ((kblcode == 2) && ((wcc & 0x02) == 0)) {
  205.         kblcode = 1;
  206.         if (!int_active) newstat();
  207.         }
  208.     }
  209. else {
  210.     kblock = 1;
  211.     kblcode = 2;
  212.     if (!int_active) newstat();
  213.     }
  214. if (ew) if (wcc & 0x40)            /* wcc reset in EW/EWA */
  215.     if (!int_active) clrpict();        /* erase graphics */
  216.     else pndclr = 1;
  217. }
  218.  
  219. endwcc()
  220. {
  221. if (lastwcc & 0x04) if (!(int_active || tcpflg)) beep();
  222.                     else pndbeep = 1;
  223. if (lastwcc & 0x02) rdaid = 0x60;    /* reset last AID */
  224. if (cs.curpos) {
  225.     x = curadr%scrhsize;
  226.     y = curadr/scrhsize;
  227.     }
  228. if ((lastwcc & 0x82) != 0x80) {
  229.     kblock = 0;
  230.     kblcode = 0;
  231.     if (!int_active) newstat();
  232.     }
  233. else if (cs.curpos) if (!int_active) newstat();
  234.  
  235. checkfmt();            /* check that fmtscrn is still correct */
  236. }
  237.  
  238. checkfmt()        /* check all attributes have not been overwritten by data */
  239. {
  240. register short i;
  241.                 /* unformatted is always correct */
  242. if (fmtscrn == 0) return;
  243.                 /* formatted if attribute where we last put one */
  244. if (atrbuff[attrloc] & 0x8000) return;
  245.                 /* else look for an attribute byte */
  246. for (i=0; i < maxcnt; i++)
  247.     if (atrbuff[i] & 0x8000) return;
  248.                 /* all attributes were overwritten: reset flag */
  249. fmtscrn = 0;
  250. }
  251.  
  252. intsf(attr)
  253. unsigned char attr;
  254. {
  255.  
  256. chrbuff[bufadr] = 0x1d;
  257. atrbuff[bufadr] = 0x8000 + ((attr & 0x3f) << 8);
  258. attrloc = bufadr;
  259. bufadr++;
  260. if (bufadr == maxcnt) bufadr = 0;
  261. fmtscrn = 1;
  262. }
  263.  
  264. intsba(a1, a2)
  265. unsigned char a1, a2;
  266. {
  267. bufadr = cvtadr(a1, a2);
  268. }
  269.  
  270. intic()
  271. {
  272. curadr = bufadr;
  273. }
  274.  
  275. intpt()
  276. {
  277. register unsigned short a; 
  278.  
  279. while (true) {            /* loop through protected fields */
  280.     while (!(atrbuff[bufadr] & 0x8000)) {    /* get to next attribute */
  281.         if (ptfill) setnull();        /* fill with nulls if set */
  282.         else {
  283.             bufadr++;
  284.             if (bufadr == maxcnt) bufadr = 0;
  285.             }
  286.         if (bufadr == 0) return;
  287.         }
  288.     ptfill = 0;                    /* no nulls after first field */
  289.     a = atrbuff[bufadr];        /* get attributes for this field */
  290.     bufadr++;                    /* increment buffer address */
  291.     if (bufadr == maxcnt) {
  292.         bufadr = 0;                /* done if wrapped */
  293.         return;
  294.         }
  295.     if (!(a & 0x2000)) return;    /* found field if unprotected */
  296.     }
  297. }
  298.  
  299. intra(a1, a2, c, g)
  300. unsigned char a1, a2, c, g;
  301. {
  302. register short endadr;
  303.  
  304. endadr = cvtadr(a1, a2);
  305. do intdata(c,g); while (endadr != bufadr);
  306. }
  307.  
  308. inteua(a1, a2)
  309. unsigned char a1, a2;
  310. {
  311. register unsigned char skip, nofmt;
  312. register short endadr, addr, prot;
  313.  
  314. endadr = cvtadr(a1, a2);
  315. addr = bufadr;            /* find previous attribute */
  316. nofmt = 0;
  317. while (!(atrbuff[addr] & 0x8000)) {
  318.     if (addr == 0) {
  319.         nofmt = 1;
  320.         break;
  321.         }
  322.     else addr--;
  323.     }
  324. if (nofmt) prot = 0;
  325. else prot = atrbuff[addr] & 0x2000;
  326. skip = 0;
  327. do {
  328.     if (atrbuff[bufadr] & 0x8000) {
  329.         prot = atrbuff[bufadr] & 0x2000;
  330.         skip = 1;
  331.         }
  332.     else if (!prot) {
  333.         if (skip) {
  334.             skip = 0;
  335.             }
  336.         setnull();
  337.         }
  338.          else skip = 1;
  339.     if (skip) {
  340.         bufadr++;
  341.         if (bufadr == maxcnt) bufadr = 0;
  342.         }
  343.     } while (endadr != bufadr);
  344. }
  345.  
  346. intsfe(field, pairs)
  347. unsigned char * field;
  348. unsigned char pairs;
  349. {
  350. atrbuff[bufadr] = intpairs(0x8000, field, pairs);
  351. chrbuff[bufadr] = 0x1d;
  352. attrloc = bufadr;
  353. bufadr++;
  354. if (bufadr == maxcnt) bufadr = 0;
  355. fmtscrn = 1;
  356. }
  357.  
  358. intmf(field, pairs)
  359. unsigned char * field;
  360. unsigned char pairs;
  361. {
  362. register short atr;
  363.  
  364. atr = intpairs(atrbuff[bufadr], field, pairs);
  365. if (atr & 0x8000) {
  366.     atrbuff[bufadr] = atr;
  367.     chrbuff[bufadr] = 0x1d;
  368.     }
  369. bufadr++;
  370. if (bufadr == maxcnt) bufadr = 0;
  371. }
  372.  
  373. intsa(type, value)
  374. unsigned char type, value;
  375. {
  376. register unsigned char safield[2];
  377.  
  378. if ((type == 0) && (value == 0)) {
  379.     chratr = 0;
  380.     return;
  381.     }
  382. safield[0] = type;
  383. safield[1] = value;
  384. chratr = intpairs(chratr, safield, 1);
  385. }
  386.  
  387. intpairs(atr, field, pairs)
  388. unsigned short atr;
  389. unsigned char * field;
  390. unsigned char pairs;
  391. {
  392. register unsigned char c;
  393. register short offset;
  394.  
  395. offset = 0;
  396. while (pairs > 0) {
  397.     c = field[offset+1];
  398.     switch(field[offset]) {
  399.  
  400.     case 0xC0:    atr &= 0xC0FF;
  401.             atr += (c & 0x3f) << 8;
  402.             break;
  403.  
  404.     case 0x41:    atr &= 0xFFE7;
  405.             if (c ==  0xF4) c = 0xF3;
  406.             atr += (c & 0x03) << 3;
  407.             break;
  408.  
  409.     case 0x42:    atr &= 0xFFF8;
  410.             if ((c & 0x07) == 0) break;
  411.             /* if (c == 0) c = 0xF4; */
  412.             atr += c & 0x07;
  413.             colorfield = 1;
  414.             break;
  415.     case 0x43:    atr &= 0xFF3F;
  416.             atr += (c & 0x03) << 6;
  417.             break;
  418.     default:    break;
  419.     }
  420.     offset += 2;
  421.     pairs--;
  422.     }
  423. return(atr);
  424. }
  425.  
  426. intdata(code, geflag)
  427. unsigned char code, geflag;
  428. {
  429. register unsigned char a, f;
  430.  
  431. chrbuff[bufadr] = code;
  432. atrbuff[bufadr] = chratr;
  433. if ((code == 0xad) || (code == 0xbd))
  434.     if (fixbracket) geflag = 1;
  435. if (geflag) atrbuff[bufadr] += 0x4000;
  436. bufadr++;
  437. if (bufadr == maxcnt) bufadr = 0;
  438. }
  439.  
  440. setnull()
  441. {
  442. chrbuff[bufadr] = 0;
  443. atrbuff[bufadr] = 0;
  444. bufadr++;
  445. if (bufadr == maxcnt) bufadr = 0;
  446. }
  447.  
  448. cvtadr(a1, a2)
  449. unsigned char a1, a2;
  450. {
  451. short a;
  452.  
  453. if ((a1 & 0xc0) == 0)        /* 14-bit address */
  454.     a = (a1 << 8) + a2;
  455. else a = ((a1 & 0x3f) << 6) + (a2 & 0x3f);    /* 12-bit address */
  456. if (a < 0) a = 0;
  457. if (a > maxoff) a = maxoff;
  458. return(a);
  459. }
  460.  
  461. orderinit()
  462. {
  463. register short i, j;
  464. static unsigned char ordercodes[] =
  465.     {0x1d, 0x11, 0x13, 0x05, 0x3c, 0x12, 0x08, 0x29, 0x2c, 0x28, 0x00};
  466.  
  467. for (i=0; i < 256; i++) ordertab[i] = 0xff;
  468. j = strlen(ordercodes);
  469. for (i=0; i < j; i++) ordertab[ordercodes[i]] = 0;
  470. }
  471.  
  472. setrectsel(offset1, offset2)
  473. short offset1, offset2;
  474. {
  475. short rowmin, rowmax, colmin, colmax, t;
  476. register short row, col;
  477.  
  478. if (offset1 == offset2) return;
  479. rowmin = offset1 / scrhsize;
  480. colmin = offset1 % scrhsize;
  481. rowmax = offset2 / scrhsize;
  482. colmax = offset2 % scrhsize;
  483. if (rowmin > rowmax) {
  484.     t = rowmax;
  485.     rowmax = rowmin;
  486.     rowmin = t;
  487.     }
  488. if (colmin > colmax) {
  489.     t = colmax;
  490.     colmax = colmin;
  491.     colmin = t;
  492.     }
  493. for (row = rowmin; row <= rowmax; row++)
  494.     for (col = colmin; col <= colmax; col++) {
  495.         if (atrbuff[scrhsize*row + col] ^= 0x0020) textsel = 1;
  496.         }
  497. invldscr();
  498. }
  499.  
  500. settextsel(offset1, offset2, invert)
  501. short offset1, offset2;
  502. char invert;
  503. {
  504. short start, end, offset;
  505.  
  506. start = offset1;
  507. end = offset2;
  508. if (end < start) {
  509.     start = offset2;
  510.     end = offset1;
  511.     }
  512. for (offset = start; offset < end; offset++) {
  513.     if (invert) {
  514.         atrbuff[offset] ^= 0x0020;
  515.         }
  516.     else {
  517.         atrbuff[offset] |= 0x0020;
  518.         }
  519.     textsel = 1;
  520.     }
  521. invldscr();
  522. }
  523.  
  524. addfieldsel()            /* select entire field for any field partly selected */
  525. {
  526. register short i;
  527. short firstpos, attrpos;
  528. char selflag;
  529.  
  530. if (!fmtscrn) return;
  531.  
  532. firstpos = 0;
  533. /* if first byte not an attribute, find attribute for first byte */
  534. if ((atrbuff[0] & 0x8000) == 0) {
  535.     firstpos = -1;
  536.     for (i = maxoff; i > 0; i--)
  537.         if (atrbuff[i] & 0x8000) {
  538.             firstpos = i;
  539.             break;
  540.             }
  541.     }
  542. if (firstpos < 0) return;
  543.  
  544. /* set selection bit for the attribute byte of each field to be selected */
  545. attrpos = firstpos;
  546. for (i=0; i < maxcnt; i++)
  547.     if (atrbuff[i] & 0x8000) {        /* attribute byte */
  548.         attrpos = i;
  549.         }
  550.     else {                            /* data byte */
  551.         if (atrbuff[i] & 0x0020) atrbuff[attrpos] |= 0x0020;
  552.         }
  553.  
  554. /* set selections bits for all bytes in selected fields */
  555. selflag = (atrbuff[firstpos] & 0x0020) == 0x0020;
  556. for (i=0; i < maxcnt; i++)
  557.     if (atrbuff[i] & 0x8000) {        /* attribute byte */
  558.         selflag = (atrbuff[i] & 0x0020) == 0x0020;
  559.         }
  560.     else {
  561.         if (selflag) atrbuff[i] |= 0x0020;
  562.         }
  563.  
  564. /* reset selection bits in the field attributes */
  565. for (i=0; i < maxcnt; i++)
  566.     if (atrbuff[i] & 0x8000) atrbuff[i] &= 0xffdf;
  567. }
  568.  
  569. resetsel()
  570. {
  571. register short i;
  572. char selflag;
  573.  
  574. selflag = 0;
  575. for (i = 0; i < maxcnt; i++) {
  576.     if (atrbuff[i] & 0x0020) {
  577.         selflag = 1;
  578.         atrbuff[i] &= 0xffdf;
  579.         }
  580.     }
  581. textsel = 0;
  582. if (selflag) invldscr();
  583. }
  584.  
  585. checksel()        /* check if there really is selected text */
  586. {
  587. register short i;
  588.  
  589. textsel = 0;
  590. for (i=0; i < maxcnt; i++) {
  591.     if (atrbuff[i] & 0x0020) {
  592.         textsel = 1;
  593.         return;
  594.         }
  595.     }
  596. }
  597.  
  598. addsel(downloc)        /* find new starting point for extending text selection */
  599. short * downloc;
  600. {
  601. short startoff, endoff;
  602. register short i;
  603.  
  604. for (i=0; i < maxcnt; i++)            /* get first selection offset */
  605.     if (atrbuff[i] & 0x0020) {
  606.         startoff = i;
  607.         break;        
  608.         }
  609. for (i=maxoff; i >= 0; i--)
  610.     if (atrbuff[i] & 0x0020) {
  611.         endoff = i;
  612.         break;
  613.         }
  614. if ((*downloc) < startoff)
  615.      (*downloc) = endoff + 1;
  616. else (*downloc) = startoff;
  617. }
  618.  
  619. wordadj(loc1, loc2, endadj)
  620. short *loc1, *loc2;
  621. char endadj;
  622. {
  623. short startloc, endloc;
  624. short startline, endline;
  625. char swapped;
  626.  
  627. swapped = 0;
  628. startloc = *loc1;
  629. endloc = *loc2;
  630. if (startloc > endloc) {
  631.     startloc = *loc2;
  632.     endloc = *loc1;
  633.     swapped = 1;
  634.     }
  635. endloc -= endadj;
  636. if (endloc < 0) return;
  637.  
  638. startline = startloc/scrhsize;
  639. endline = endloc/scrhsize;
  640. while ((!atspace(startloc)) && (startloc > 0) &&
  641.        ((startloc-1)/scrhsize == startline)) startloc--;
  642. while ((atspace(startloc)) && (startloc < endloc) &&
  643.        ((startloc+1)/scrhsize <= endline)) startloc++;
  644. while ((!atspace(endloc)) && (endloc < maxoff) &&
  645.        ((endloc+1)/scrhsize == endline)) endloc++;
  646. while ((atspace(endloc)) && (endloc > startloc) &&
  647.        ((endloc-1)/scrhsize >= startline)) endloc--;
  648. if (atspace(startloc) && atspace(endloc)) return;
  649.  
  650. endloc += endadj;
  651.  
  652. if (swapped) {
  653.     *loc2 = startloc;
  654.     *loc1 = endloc;
  655.     }
  656. else {
  657.     *loc1 = startloc;
  658.     *loc2 = endloc;
  659.     }
  660. }
  661.  
  662. atspace(loc)
  663. short loc;
  664. {
  665. if (chrbuff[loc] == 0x40) return(1);
  666. if (chrbuff[loc] == 0x00) return(1);
  667. if (atrbuff[loc] & 0x8000) return(1);
  668. return(0);
  669. }